#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
集群管理页面模块
"""

import logging
from PyQt6.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton,
    QTabWidget, QFrame, QGridLayout, QLineEdit, QComboBox,
    QCheckBox, QSpinBox, QFileDialog, QMessageBox, QListWidget,
    QListWidgetItem, QTableWidget, QTableWidgetItem, QHeaderView,
    QProgressBar, QDialog, QFormLayout, QDialogButtonBox
)
from PyQt6.QtCore import Qt, QTimer
from PyQt6.QtGui import QIcon, QColor


class NodeDialog(QDialog):
    """节点编辑对话框"""
    
    def __init__(self, node_data=None, parent=None):
        super().__init__(parent)
        self.node_data = node_data or {}
        self.setWindowTitle("编辑节点")
        self.resize(400, 300)
        self._setup_ui()
    
    def _setup_ui(self):
        """设置UI"""
        layout = QVBoxLayout(self)
        
        # 节点信息表单
        form_layout = QFormLayout()
        
        # 节点名称
        self.name_edit = QLineEdit(self.node_data.get("name", ""))
        form_layout.addRow("节点名称:", self.name_edit)
        
        # 节点地址
        self.host_edit = QLineEdit(self.node_data.get("host", "localhost"))
        form_layout.addRow("主机地址:", self.host_edit)
        
        # 节点端口
        self.port_spinbox = QSpinBox()
        self.port_spinbox.setRange(1000, 65535)
        self.port_spinbox.setValue(self.node_data.get("port", 8000))
        form_layout.addRow("端口:", self.port_spinbox)
        
        # 最大工作进程数
        self.workers_spinbox = QSpinBox()
        self.workers_spinbox.setRange(1, 32)
        self.workers_spinbox.setValue(self.node_data.get("max_workers", 4))
        form_layout.addRow("最大工作进程数:", self.workers_spinbox)
        
        # 启用状态
        self.enabled_checkbox = QCheckBox("启用节点")
        self.enabled_checkbox.setChecked(self.node_data.get("enabled", True))
        form_layout.addRow("", self.enabled_checkbox)
        
        layout.addLayout(form_layout)
        
        # 按钮
        button_box = QDialogButtonBox(
            QDialogButtonBox.StandardButton.Save | QDialogButtonBox.StandardButton.Cancel
        )
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)
        layout.addWidget(button_box)
    
    def get_node_data(self):
        """获取节点数据"""
        return {
            "name": self.name_edit.text(),
            "host": self.host_edit.text(),
            "port": self.port_spinbox.value(),
            "max_workers": self.workers_spinbox.value(),
            "enabled": self.enabled_checkbox.isChecked()
        }


class ClusterPage(QWidget):
    """集群管理页面"""
    
    def __init__(self, config, database=None, task_scheduler=None):
        super().__init__()
        self.config = config
        self.database = database
        self.task_scheduler = task_scheduler
        self.nodes = []  # 节点列表
        self._setup_ui()
        self._load_nodes()
        
        # 设置定时器更新节点状态
        self.update_timer = QTimer(self)
        self.update_timer.timeout.connect(self._update_node_status)
        self.update_timer.start(3000)  # 3秒更新一次
        
        logging.info("集群管理页面已初始化")
    
    def _setup_ui(self):
        """设置UI"""
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(20, 20, 20, 20)
        
        # 标题
        title_label = QLabel("集群管理")
        title_label.setStyleSheet("font-size: 24px; font-weight: bold;")
        main_layout.addWidget(title_label)
        
        # 集群状态区域
        status_frame = QFrame()
        status_frame.setFrameShape(QFrame.Shape.StyledPanel)
        status_frame.setStyleSheet("background-color: #f8f9fa; border-radius: 8px;")
        status_layout = QVBoxLayout(status_frame)
        
        status_title = QLabel("集群状态")
        status_title.setStyleSheet("font-size: 18px; font-weight: bold;")
        status_layout.addWidget(status_title)
        
        # 集群状态信息
        cluster_status_layout = QHBoxLayout()
        cluster_status_layout.addWidget(QLabel("状态:"))
        self.cluster_status_label = QLabel("未启用")
        self.cluster_status_label.setStyleSheet("color: #7f8c8d;")
        cluster_status_layout.addWidget(self.cluster_status_label)
        cluster_status_layout.addStretch()
        status_layout.addLayout(cluster_status_layout)
        
        # 节点数量信息
        node_count_layout = QHBoxLayout()
        node_count_layout.addWidget(QLabel("节点数量:"))
        self.node_count_label = QLabel("0")
        node_count_layout.addWidget(self.node_count_label)
        node_count_layout.addStretch()
        status_layout.addLayout(node_count_layout)
        
        # 活动节点信息
        active_node_layout = QHBoxLayout()
        active_node_layout.addWidget(QLabel("活动节点:"))
        self.active_node_label = QLabel("0")
        active_node_layout.addWidget(self.active_node_label)
        active_node_layout.addStretch()
        status_layout.addLayout(active_node_layout)
        
        # 总工作进程信息
        workers_layout = QHBoxLayout()
        workers_layout.addWidget(QLabel("总工作进程:"))
        self.workers_label = QLabel("0")
        workers_layout.addWidget(self.workers_label)
        workers_layout.addStretch()
        status_layout.addLayout(workers_layout)
        
        main_layout.addWidget(status_frame)
        
        # 节点列表区域
        nodes_frame = QFrame()
        nodes_frame.setFrameShape(QFrame.Shape.StyledPanel)
        nodes_layout = QVBoxLayout(nodes_frame)
        
        nodes_header = QHBoxLayout()
        nodes_header.addWidget(QLabel("节点列表"))
        
        # 新建节点按钮
        new_node_btn = QPushButton("新建节点")
        new_node_btn.clicked.connect(self._create_node)
        nodes_header.addWidget(new_node_btn)
        
        # 刷新按钮
        refresh_btn = QPushButton("刷新")
        refresh_btn.clicked.connect(self._refresh_nodes)
        nodes_header.addWidget(refresh_btn)
        
        # 启用集群按钮
        self.enable_cluster_btn = QPushButton("启用集群")
        self.enable_cluster_btn.clicked.connect(self._toggle_cluster)
        nodes_header.addWidget(self.enable_cluster_btn)
        
        nodes_layout.addLayout(nodes_header)
        
        # 节点表格
        self.node_table = QTableWidget()
        self.node_table.setColumnCount(7)
        self.node_table.setHorizontalHeaderLabels(["名称", "地址", "端口", "状态", "CPU使用率", "内存使用率", "工作进程"])
        self.node_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
        self.node_table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
        self.node_table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
        self.node_table.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeMode.ResizeToContents)
        self.node_table.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeMode.ResizeToContents)
        self.node_table.horizontalHeader().setSectionResizeMode(5, QHeaderView.ResizeMode.ResizeToContents)
        self.node_table.horizontalHeader().setSectionResizeMode(6, QHeaderView.ResizeMode.ResizeToContents)
        self.node_table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
        self.node_table.setSelectionMode(QTableWidget.SelectionMode.SingleSelection)
        self.node_table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
        self.node_table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.node_table.customContextMenuRequested.connect(self._show_node_context_menu)
        
        nodes_layout.addWidget(self.node_table)
        
        main_layout.addWidget(nodes_frame)
    
    def _load_nodes(self):
        """加载节点列表"""
        # 这里应该从配置或数据库加载节点列表
        # 目前使用模拟数据
        self.nodes = [
            {
                "name": "主节点",
                "host": "localhost",
                "port": 8000,
                "max_workers": 4,
                "enabled": True,
                "status": "在线",
                "cpu_usage": 25,
                "memory_usage": 40,
                "active_workers": 2
            },
            {
                "name": "工作节点1",
                "host": "192.168.1.101",
                "port": 8000,
                "max_workers": 8,
                "enabled": True,
                "status": "在线",
                "cpu_usage": 15,
                "memory_usage": 30,
                "active_workers": 3
            },
            {
                "name": "备份节点",
                "host": "192.168.1.102",
                "port": 8000,
                "max_workers": 4,
                "enabled": False,
                "status": "离线",
                "cpu_usage": 0,
                "memory_usage": 0,
                "active_workers": 0
            },
        ]
        
        # 更新集群状态
        self._update_cluster_status()
        
        # 更新节点表格
        self._update_node_table()
    
    def _update_cluster_status(self):
        """更新集群状态"""
        # 检查集群是否启用
        cluster_enabled = self.config.get("cluster", {}).get("enabled", False)
        
        if cluster_enabled:
            self.cluster_status_label.setText("运行中")
            self.cluster_status_label.setStyleSheet("color: #2ecc71; font-weight: bold;")
            self.enable_cluster_btn.setText("禁用集群")
        else:
            self.cluster_status_label.setText("未启用")
            self.cluster_status_label.setStyleSheet("color: #7f8c8d;")
            self.enable_cluster_btn.setText("启用集群")
        
        # 统计节点信息
        total_nodes = len(self.nodes)
        active_nodes = sum(1 for node in self.nodes if node["status"] == "在线")
        total_workers = sum(node["active_workers"] for node in self.nodes if node["status"] == "在线")
        
        self.node_count_label.setText(str(total_nodes))
        self.active_node_label.setText(str(active_nodes))
        self.workers_label.setText(str(total_workers))
    
    def _update_node_table(self):
        """更新节点表格"""
        self.node_table.setRowCount(0)
        
        for node in self.nodes:
            row = self.node_table.rowCount()
            self.node_table.insertRow(row)
            
            self.node_table.setItem(row, 0, QTableWidgetItem(node["name"]))
            self.node_table.setItem(row, 1, QTableWidgetItem(node["host"]))
            self.node_table.setItem(row, 2, QTableWidgetItem(str(node["port"])))
            
            status_item = QTableWidgetItem(node["status"])
            status_color = "#2ecc71" if node["status"] == "在线" else "#e74c3c"
            status_item.setForeground(QColor(status_color))
            self.node_table.setItem(row, 3, status_item)
            
            # CPU使用率进度条
            cpu_progress = QProgressBar()
            cpu_progress.setRange(0, 100)
            cpu_progress.setValue(node["cpu_usage"])
            cpu_progress.setTextVisible(True)
            cpu_progress.setFormat("%p%")
            self.node_table.setCellWidget(row, 4, cpu_progress)
            
            # 内存使用率进度条
            memory_progress = QProgressBar()
            memory_progress.setRange(0, 100)
            memory_progress.setValue(node["memory_usage"])
            memory_progress.setTextVisible(True)
            memory_progress.setFormat("%p%")
            self.node_table.setCellWidget(row, 5, memory_progress)
            
            self.node_table.setItem(row, 6, QTableWidgetItem(f"{node['active_workers']}/{node['max_workers']}"))
    
    def _show_node_context_menu(self, position):
        """显示节点上下文菜单"""
        current_row = self.node_table.currentRow()
        
        if current_row >= 0:
            menu = QMenu()
            
            # 编辑节点
            edit_action = QAction("编辑节点", self)
            edit_action.triggered.connect(self._edit_node)
            menu.addAction(edit_action)
            
            # 获取当前节点
            node = self.nodes[current_row]
            
            # 启用/禁用节点
            if node["enabled"]:
                disable_action = QAction("禁用节点", self)
                disable_action.triggered.connect(lambda: self._toggle_node(False))
                menu.addAction(disable_action)
            else:
                enable_action = QAction("启用节点", self)
                enable_action.triggered.connect(lambda: self._toggle_node(True))
                menu.addAction(enable_action)
            
            # 删除节点
            delete_action = QAction("删除节点", self)
            delete_action.triggered.connect(self._delete_node)
            menu.addAction(delete_action)
            
            menu.exec(self.node_table.mapToGlobal(position))
    
    def _create_node(self):
        """创建新节点"""
        dialog = NodeDialog(parent=self)
        if dialog.exec():
            node_data = dialog.get_node_data()
            # 添加默认状态信息
            node_data.update({
                "status": "离线",
                "cpu_usage": 0,
                "memory_usage": 0,
                "active_workers": 0
            })
            self.nodes.append(node_data)
            self._update_cluster_status()
            self._update_node_table()
            logging.info(f"已创建节点: {node_data['name']}")
    
    def _edit_node(self):
        """编辑节点"""
        current_row = self.node_table.currentRow()
        if current_row >= 0:
            node = self.nodes[current_row]
            dialog = NodeDialog(node, parent=self)
            if dialog.exec():
                updated_data = dialog.get_node_data()
                # 更新节点数据，保留状态信息
                node.update(updated_data)
                self._update_cluster_status()
                self._update_node_table()
                logging.info(f"已更新节点: {node['name']}")
    
    def _delete_node(self):
        """删除节点"""
        current_row = self.node_table.currentRow()
        if current_row >= 0:
            node = self.nodes[current_row]
            reply = QMessageBox.question(
                self, "确认删除", f"确定要删除节点 '{node['name']}' 吗？",
                QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
                QMessageBox.StandardButton.No
            )
            
            if reply == QMessageBox.StandardButton.Yes:
                del self.nodes[current_row]
                self._update_cluster_status()
                self._update_node_table()
                logging.info(f"已删除节点: {node['name']}")
    
    def _toggle_node(self, enabled):
        """切换节点启用状态"""
        current_row = self.node_table.currentRow()
        if current_row >= 0:
            node = self.nodes[current_row]
            node["enabled"] = enabled
            if not enabled:
                node["status"] = "离线"
                node["cpu_usage"] = 0
                node["memory_usage"] = 0
                node["active_workers"] = 0
            self._update_cluster_status()
            self._update_node_table()
            status = "启用" if enabled else "禁用"
            logging.info(f"已{status}节点: {node['name']}")
    
    def _toggle_cluster(self):
        """切换集群启用状态"""
        cluster_enabled = self.config.get("cluster", {}).get("enabled", False)
        new_status = not cluster_enabled
        
        # 更新配置
        if "cluster" not in self.config:
            self.config["cluster"] = {}
        self.config["cluster"]["enabled"] = new_status
        
        # 更新UI
        self._update_cluster_status()
        
        status = "启用" if new_status else "禁用"
        logging.info(f"已{status}集群")
    
    def _update_node_status(self):
        """更新节点状态"""
        # 这里应该从各节点获取最新状态
        # 目前只是模拟状态变化
        import random
        
        for node in self.nodes:
            if node["enabled"] and node["status"] == "在线":
                # 随机变化CPU和内存使用率
                node["cpu_usage"] = min(100, max(0, node["cpu_usage"] + random.randint(-5, 5)))
                node["memory_usage"] = min(100, max(0, node["memory_usage"] + random.randint(-3, 3)))
            elif node["enabled"] and random.random() < 0.1:  # 10%概率上线
                node["status"] = "在线"
                node["cpu_usage"] = random.randint(10, 30)
                node["memory_usage"] = random.randint(20, 50)
                node["active_workers"] = random.randint(1, node["max_workers"])
        
        # 更新UI
        self._update_cluster_status()
        self._update_node_table()
    
    def _refresh_nodes(self):
        """刷新节点列表"""
        # 这里应该从配置或后端获取最新的节点列表
        # 目前只是重新加载现有数据
        self._update_cluster_status()
        self._update_node_table()
        logging.info("已刷新节点列表")